package com.tcm.common.Interceptor;

import com.tcm.common.enums.CachePrefix;
import com.tcm.entity.bo.UserCacheBo;
import com.tcm.utils.AccessTokenUtil;
import com.tcm.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * WebSocket请求拦截器（已纳入Spring IoC容器管理）
 * @author Guqier
 * @version 1.0
 * @date 2023/9/14 21:42
 */
@Slf4j
public class WebSocketAuthInterceptor implements HandshakeInterceptor {

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean beforeHandshake(@NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response, @NonNull WebSocketHandler wsHandler, @NonNull Map<String, Object> attributes) throws Exception {
        // 转换Request对象
        HttpServletRequest httpServletRequest = ((ServletServerHttpRequest) request).getServletRequest();
        String accessToken = httpServletRequest.getParameter("token");
        // 如果没有accessToken信息，同样不予放行
        if (!StringUtils.hasText(accessToken)) {
            return false;
        }

        // 校验AccessToken
        boolean res = AccessTokenUtil.verifyAccessToken(accessToken);
        if (res){
            // 校验缓存中的登录信息
            Long userId = AccessTokenUtil.getUserId(accessToken);
            UserCacheBo userCacheBo = redisUtil.getCacheObject(CachePrefix.PC_USER_TOKEN.getCacheKey(String.valueOf(userId)));
            if (!accessToken.equals(userCacheBo != null ? userCacheBo.getToken() : null)) {
                // 查询延迟校验是否存在
                String oldToken = redisUtil.getCacheObject(CachePrefix.PC_TOKEN_DELAYED_FILTERING.getCacheKey(String.valueOf(userId)));
                if (!accessToken.equals(oldToken)){
                    return false;
                }
            }
            attributes.put("userId", userId);
            log.info("WebSocket连接：{} 用户账号：{} 已放行", request.getRemoteAddress().getHostString(), AccessTokenUtil.getUserAccount(accessToken));
            return true;  //请求放行
        }else {
            // 校验不通过则拦截请求
            return false;
        }
    }

    @Override
    public void afterHandshake( @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response, @NonNull WebSocketHandler wsHandler, Exception exception) {

    }
}
